﻿/*
   Copyright 2011 Andrew Davis

    This file is part of DeviousCreation.Base.

    DeviousCreation.Base is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    DeviousCreation.Base is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with DeviousCreation.Base.  If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlServerCe;
using DeviousCreation.Components.Methods;
using System.ComponentModel;
using System.Web.Script.Serialization;

namespace DeviousCreation.Base.SQLCE
{
    [Serializable()]
    public abstract class BaseClass
    {
        #region "Member Varibles"
        protected int mID;
        #endregion

        #region "Member Varible Access"
        public int ID
        {
            get { return mID; }
        }
        #endregion

        #region "Public Events"
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #region "Variables"
        protected ObjectStatus objectStatus;
        protected string connStr;
        #endregion

        #region "Construtors"
        protected BaseClass() { }
        protected BaseClass(int id)
        {
            mID = id;
        }
        #endregion

        #region "Protected Methods"
        protected void NotifyPropertyChanged(string info)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
        #endregion

        #region "Public Methods"
        public virtual void MarkAsDeleted()
        {
            NotifyPropertyChanged("Deleted");
            objectStatus = ObjectStatus.isOld;
        }
        public virtual string ToJSON()
        {
            JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
            return javaScriptSerializer.Serialize(this);
        }
        #endregion

        #region "CRUD"
        public bool Update(string connStr)
        {
            this.connStr = connStr;
            SqlCeConnection conn = new SqlCeConnection(connStr);
            SqlCeTransaction trans = null;
            try
            {
                bool result;
                SqlCeCommand comm;
                switch (objectStatus)
                {
                    case ObjectStatus.isNew:
                        // CALL CREATE
                        conn.Open();
                        trans = conn.BeginTransaction();
                        comm = new SqlCeCommand();
                        comm.Transaction = trans;
                        comm.Connection = conn;
                        result = Create(ref comm);
                        trans.Commit();
                        return result;
                    case ObjectStatus.isDirty:
                        // CALL UPDATE
                        conn.Open();
                        trans = conn.BeginTransaction();
                        comm = new SqlCeCommand();
                        comm.Transaction = trans;
                        comm.Connection = conn;
                        result = Update(ref comm);
                        trans.Commit();
                        return result;
                    case ObjectStatus.isOld:
                        // CALL DELETE
                        conn.Open();
                        trans = conn.BeginTransaction();
                        comm = new SqlCeCommand();
                        comm.Transaction = trans;
                        comm.Connection = conn;
                        result = Delete(ref comm);
                        trans.Commit();
                        return result;
                }
                return true;
            }
            catch (Exception ex)
            {
                trans.Rollback();
                Log.LogError(ex, true, true, true);
                return false;
            }
            finally
            {
                conn.Close();
            }
        }
        #region "Database Access"
        protected abstract bool Create(ref SqlCeCommand comm);
        protected abstract bool Update(ref SqlCeCommand comm);
        protected abstract bool Delete(ref SqlCeCommand comm);
        #endregion
        #endregion

        #region "Public Static Methods"
        public static BaseClass FromJSON(string json)
        {
            JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
            return javaScriptSerializer.Deserialize<BaseClass>(json);
        }
        #endregion
    }
}
